//============================================================================
// Name        : RWlock.cpp
// Author      : Nivard Koskamp en Pleun Willemsen
// Version     :
// Copyright   : Saxion - Informatica
// Description : Database Monitor
//============================================================================

#include "RWlock.h"
#include "conc/Thread.h"
#include <iostream>
using namespace std;

RWlock::RWlock() :
	Monitor("RWlock", 2) {
	aantalWachtendeSchrijvers = 0;
	aantalWachtendeLezers = 0;
	aantalHuidigeLezers = 0;
	wordtGeschreven = false;

	//Geef aan wie er voorrang heeft:
	//True = schrijvers voorrang
	//False = lezers voorrang
	schrijversVoorrang = true;
}

//Toelichting:
//WAIT(0) = lezers wachtrij
//WAIT(1) = schrijvers wachtrij

//ReadLock
void RWlock::RDlock(int nummer) {
	ENTER();
	if ((aantalWachtendeSchrijvers == 0 || !schrijversVoorrang)	&& !wordtGeschreven) {

		cout << "--> Lezer:" << nummer << " leest." << endl;

		aantalHuidigeLezers++;
	} else {
		aantalWachtendeLezers++;
		cout << "^^^ Lezer: " << nummer	<< " moet in de wacht" << endl;
		WAIT(0);
		aantalWachtendeLezers--;
		aantalHuidigeLezers++;
		cout << "--> Lezer: " << nummer << " komt uit de wacht en leest."<< endl;

	}
	LEAVE();
}

//WriteLock
void RWlock::WRlock(int nummer) {
	ENTER();
	if (aantalHuidigeLezers == 0 && !wordtGeschreven) {
		cout << "<-- Schrijver: " << nummer << " schrijft." << endl;

		wordtGeschreven = true;
	} else {
		aantalWachtendeSchrijvers++;
		cout << "^^^ Schrijver: " << nummer	<< " moet in de wacht"<< endl;
		WAIT(1);
		aantalWachtendeSchrijvers--;
		wordtGeschreven = true;
		cout << "<-- Schrijver: " << nummer	<< " komt uit de wacht en schrijft." << endl;
	}

	LEAVE();
}

//Unlock process --> schrijvers krijgen voorrang op lezers
void RWlock::Unlock(int nummer) {
	ENTER();

	if (wordtGeschreven) {//Nu komt er een schijver binnen
		cout << "Threadnr: " << nummer << " klaar met schrijven" << endl;
		wordtGeschreven = false;
		if (schrijversVoorrang && aantalWachtendeSchrijvers > 0) {

			NOTIFY(1);
		} else if (aantalWachtendeSchrijvers > 0 && aantalWachtendeLezers == 0) {
			NOTIFY(1);
		} else {
			NOTIFYALL(0);
		}
	} else {//Nu komt er een lezer binnen
		cout << "Threadnr: " << nummer << " klaar met lezen" << endl;
		aantalHuidigeLezers--;
		if (!schrijversVoorrang && aantalWachtendeLezers > 0) {
			NOTIFYALL(0);
		} else if (aantalHuidigeLezers == 0) {
			NOTIFY(1);
		}
	}



	LEAVE();

}

